#include <stdio.h>
#include <threads.h>
enum{NTHREADS = 5};
etx_t mutex;
cnd_t cond;
int run_step(void *t){
    static int current_step = 0;
    size_t my_step = *(size_t *)t;
    if (thrd_success != mtx_lock(&mutex)){
        /* Handle error */
    }
    printf("Thread %d has the lock\n",my_step);
    while(current_step != my_step){
        printf("Thread %d is sleeping...\n",my_step);
        if (thrd_success != cnd_wait(&cond,&mutex)){
            /* Handle error */
        }
        printf("Thread %d woke up\n",my_step);
    }
    /* Do processing ... */
    printf("Thread %d is processing...\n",my_step);
    current_step++;

    /* Signal a waiting task */
    if (thrd_success != cnd_broadcast(&cond)){
        /* Handle error */
    }

    printf("Thread %d is exiting...\n",my_step);

    if(thrd_success != mtx_unlock(&mutex)){
        /* Handle error */
    }
    return 0;
}

int main(void){
    thrd_t threads[NTHREADS];
    size_t step[NTHREADS];
    if (thrd_success != mtx_init(&mutex,mtx_plain)){
        /* Handle error */
    }

    if (thrd_success != cnd_init(&cond)){
        /* Handle error */
    }

    /* Create threads */
    for (size_t i = 0;i < NTHREADS;++i){
        step[i] = i;
        if (thrd_success != thrd_create(&threads[i],run_step,&step[i])){
            /* Handle error */
        }
    }

    /* Wait for all threads to complete */
    for (size_t i = NTHREADS;i != 0;--i){
        if (thrd_success != thrd_join(threads[i-1],NULL)){
            /* Handle error */
        }
    }

    mtx_destroy(&mutex);
    cnd_destroy(&cond);
    return 0;
}